def AutoMap(vtop, ptop, preference.xml):

  nodeTypes <- types of testbed machines requested in vtop
  For ntype in nodeTypes:
    ntypeReq <- number of ntype nodes in vtop
    ntypeAvailable <- number of ntype machines in ptop
    if ntypeReq < ntypeAvailable:
      continue

    #Generate a new topology that contians nodes of ntype
    singleTypeTopology = NULL
    For node in vtop.nodes():
      if node.type == ntype:
        singleTypeTopology += node
      vtop.nodes() -= node
    For link in vtop.links():
      (n1,n2) <- the start and end nodes of link
      if (n1.type == ntype) and (n2.type == ntype):
        singleTypeTopology += link
        vtop.links() -= link

    #Scaling sub-topologies
    subTopologies <- separate singleTypeTopology into a set of sub-topologies specified by user
    For subTopology in subTopologies:
      dsplugin <- downscale plugin for subTopology selected by user
      topSize <- number of nodes in subTopology
      initSize <- Min(topSize, ntypeAvailable)
      For targetSize in Range(initSize):
        partialMap <- dsplugin(subTopology, targetSize)
        mappings[subTopology, targetSize] <- partialMap
        scores[subTopology, targetSize] <- calScore(partialMap)

    #Select the optimal mappings from all downscaled sub-topologies
  	dsMap[nodeType] <- FindOptMapping(mappings, scores, ntypeAvailable)

  #Merge all single-nodeType mappings back to vtop
  reducedTopology = vtop
  For singleTypeTopology in dsMap:	
    reducedTopology += singleTypeTopology

  #Generate scrips to launch on machines
  For node in reducedTopology:
    if multiple vnodes in vtop are mapped to node
    Scripts(node) <- generate scrapts to launch vnodes on node

  return (reducedTopology, Scripts)
